/*
  In App.xaml:
  <Application.Resources>
      <vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:TexasHoldemCalculator.MVVMLite.ViewModel"
                                   x:Key="Locator" />
  </Application.Resources>
  
  In the View:
  DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
  
  OR (WPF only):
  
  xmlns:vm="clr-namespace:TexasHoldemCalculator.MVVMLite.ViewModel"
  DataContext="{Binding Source={x:Static vm:ViewModelLocatorTemplate.ViewModelNameStatic}}"
*/

using System.Linq;
using System.Windows.Media;

using Holdem.Core.Statistics;
using Holdem.Interfaces;
using Holdem.Interfaces.Configuration;
using Holdem.Interfaces.Database;
using Holdem.Interfaces.ReplayEngine;
using Holdem.Interfaces.Security;
using Holdem.Interfaces.Service;
using Holdem.Interfaces.StartingHands;
using Holdem.Interfaces.ViewModel;

namespace Holdem.Service
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// <para>
    /// Use the <strong>mvvmlocatorproperty</strong> snippet to add ViewModels
    /// to this locator.
    /// </para>
    /// <para>
    /// In Silverlight and WPF, place the ViewModelLocatorTemplate in the App.xaml resources:
    /// </para>
    /// <code>
    /// &lt;Application.Resources&gt;
    ///     &lt;vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:TexasHoldemCalculator.MVVMLite.ViewModel"
    ///                                  x:Key="Locator" /&gt;
    /// &lt;/Application.Resources&gt;
    /// </code>
    /// <para>
    /// Then use:
    /// </para>
    /// <code>
    /// DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
    /// </code>
    /// <para>
    /// You can also use Blend to do all this with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// <para>
    /// In <strong>*WPF only*</strong> (and if databinding in Blend is not relevant), you can delete
    /// the Main property and bind to the ViewModelNameStatic property instead:
    /// </para>
    /// <code>
    /// xmlns:vm="clr-namespace:TexasHoldemCalculator.MVVMLite.ViewModel"
    /// DataContext="{Binding Source={x:Static vm:ViewModelLocatorTemplate.ViewModelNameStatic}}"
    /// </code>
    /// </summary>
    public class ViewModelLocator
    {
        private static bool _initialized;
        private static bool _setDefaultSettings;

        //public ViewModelLocator()
        //{
        //    //this.SetDefaultSettings();
        //}

        public IAdProvider AdProvider
        {
            get
            {
                this.SetDefaultSettings();

                return Factory.Instance.GetInstance<IAdProvider>();
            }
        }

        public ISkyDriveSecurityProvider SecurityProvider
        {
            get
            {
                this.SetDefaultSettings();

                return Factory.Instance.GetInstance<ISkyDriveSecurityProvider>();
            }
        }

        public IHoldemInformationViewModel Information
        {
            get
            {
                this.SetDefaultSettings();

                return Factory.Instance.GetInstance<IHoldemInformationViewModel>();
            }
        }

        public IHoldemCalculatorViewModel Main
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemCalculatorViewModel>();
            }
        }

        public IHoldemHandHistoryViewModel HandHistory
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemHandHistoryViewModel>();
            }
        }

        public IHoldemOddsViewModel Odds
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemOddsViewModel>();
            }
        }

        public IHoldemOptionsViewModel Options
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemOptionsViewModel>();
            }
        }

        public IStartingHandsViewModel StartingHands
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IStartingHandsViewModel>();
            }
        }

        public IHoldemSkyDriveViewModel SkyDrive
        {
            get { return Factory.Instance.GetInstance<IHoldemSkyDriveViewModel>(); }
        }

        public IHoldemStatisticsKickerViewModel KickerStatistics
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemStatisticsKickerViewModel>();
            }
        }

        public IHoldemStatisticsRunnerViewModel RunnerStatistics
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemStatisticsRunnerViewModel>();
            }
        }

        public IHoldemStatisticsPocketPairViewModel PairStatistics
        {
            get
            {
                this.SetDefaultSettings();

				return Factory.Instance.GetInstance<IHoldemStatisticsPocketPairViewModel>();
            }
        }

        public IHoldemStatisticsPotOddsViewModel OddsStatistics
        {
            get
            {
                this.SetDefaultSettings();

                var oddsViewModel = Factory.Instance.GetInstance<IHoldemStatisticsPotOddsViewModel>();

                if (!_initialized)
                {
                    oddsViewModel.PositiveExpectationColor = new SolidColorBrush(ColorNames.Green.FromName());
                    oddsViewModel.NegativeExpectationColor = new SolidColorBrush(ColorNames.Red.FromName());
                    _initialized = true;
                }

                return oddsViewModel;
            }
        }

        public IHoldemAboutTipViewModel About
        {
            get
            {
                this.SetDefaultSettings();

                return Factory.Instance.GetInstance<IHoldemAboutTipViewModel>();
            }
        }

        private IHoldemPhoneConfiguration PersistConfig
        {
            get
            {
                return Factory.Instance.GetInstance<IConfigurationService>().PersistentConfiguration;
            }
        }

        private void SetDefaultSettings()
        {
            if( _setDefaultSettings )
                return;

            //Calculator ViewModel
            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemCalcViewHandRank) )
                this.PersistConfig.Add(ConfigKey.HoldemCalcViewHandRank, false);
            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewHandHistorySaved) )
                this.PersistConfig[ConfigKey.HoldemOptionsViewHandHistorySaved] = false;

            //Hand History ViewModel
            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewSkipScale) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewSkipScale, 1);
            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewHandHistorySaved) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewHandHistorySaved, false);

            //Options ViewModel
            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewNumberOfPlayers) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewNumberOfPlayers, HoldemStatisticsBase.MinPlayers);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewPrecision) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewPrecision, (int)HoldemStatisticsBase.MinPrecision);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewSkipScale) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewSkipScale, 1);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewUserName) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewUserName, string.Empty);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewWriteHandHistory) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewWriteHandHistory, false);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptoinsViewCardAnimations) )
                this.PersistConfig.Add(ConfigKey.HoldemOptoinsViewCardAnimations, false);

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewHandHistorySaved) )
                this.PersistConfig.Add(ConfigKey.HoldemOptionsViewHandHistorySaved, true);

            this.PersistConfig[ConfigKey.HoldemOptionsViewHandHistorySaved] =
                !Factory.Instance.GetInstance<IHandHistoryDataContext>().IsEmpty();

            if( !this.PersistConfig.ContainsKey(ConfigKey.HoldemOptionsViewSelectedReplayEngine) )
            {
                var engines = Factory.Instance.GetInstance<IReplayEngineHost>().EngineNames.FirstOrDefault();

                if( engines != null )
                    this.PersistConfig.Add(ConfigKey.HoldemOptionsViewSelectedReplayEngine, engines);
            }

            _setDefaultSettings = true;
        }
    }
}